scenario-notebooks/Microsoft Sentinel Query Creator.ipynb (1,979 lines of code) (raw):

{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Microsoft Sentinel Query Creator Notebook\n", "\n", "This utility notebook assists in the creation of Microsoft Sentinel analytics and hunting queries by providing an interactive method for completing the required elements of the query templates and then formating this data in to the YAML format required by the Azure Sentinel GitHub repo.\n", "\n", " - [Query Style Guide](https://github.com/Azure/Azure-Sentinel/wiki/Query-Style-Guide )\n", " - [Microsoft Sentinel Contribution Guidance](https://github.com/Azure/Azure-Sentinel/wiki/Contribute-to-Sentinel-GitHub-Community-of-Queries )\n", "\n", "From time to time this notebook may fall out of sync with Microsoft Sentinel data connectors and Mitre ATT&CK elements. This this is the case you can manually adjust created queries with the required elements but please also raise an issue or PR on [GitHub](https://github.com/Azure/Azure-Sentinel-Notebooks) so that we can get this notebook updated." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Setup\n", "\n", "Run these setup cells before creating either an analytics or hunting query.\n", "\n", "Prerequisites:\n", "- [ipywidgets](https://pypi.org/project/ipywidgets/)\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import re\n", "import uuid\n", "\n", "import ipywidgets as widgets\n", "from ipywidgets import interact\n", "\n", "# Set connector options\n", "connectors = {\n", " \"AWS\": [\"AWSCloudTrail\"],\n", " \"AzureActiveDirectory\": [\n", " \"SigninLogs\",\n", " \"AuditLogs\",\n", " \"AADServicePrincipalSignInLogs\",\n", " \"AADManagedIdentitySignInLogs\",\n", " \"AADNonInteractiveUserSignInLogs\",\n", " ],\n", " \"AzureActiveDirectoryIdentityProtection\": [\"SecurityAlert (IPC)\"],\n", " \"AzureActivity\": [\"AzureActivity\"],\n", " \"AzureAdvancedThreatProtection\": [\"SecurityAlert (AATP)\"],\n", " \"AzureInformationProtection\": [\n", " \"InformationProtectionLogs_CL\",\n", " \"SecurityAlert (AIP)\",\n", " ],\n", " \"AzureMonitor(IIS)\": [\"W3CIISLog\"],\n", " \"AzureMonitor(VMInsights)\": [\"VMConnection\"],\n", " \"AzureMonitor(WireData)\": [\"WireData\"],\n", " \"AzureSecurityCenter\": [\"SecurityAlert (ASC)\"],\n", " \"IoT\": [\"SecurityAlert (ASC for IoT)\"],\n", " \"BarracudaCloudFirewall\": [\"Syslog(Barracuda)\"],\n", " \"Barracuda\": [\"CommonSecurityLog (Barracuda)\", \"Barracuda_CL\"],\n", " \"CheckPoint\": [\"CommonSecurityLog (CheckPoint)\"],\n", " \"CiscoASA\": [\"CommonSecurityLog (Cisco)\"],\n", " \"Citrix\": [\"CitrixAnalytics_SAlerts_CL\"],\n", " \"CEF\": [\"CommonSecurityLog\"],\n", " \"CyberArk\": [\"CyberArk\"],\n", " \"DNS\": [\"DnsEvents\", \"DnsInventory\"],\n", " \"ExtraHopNetworks\": [\"CommonSecurityLog ('ExtraHop')\"],\n", " \"F5BigIp\": [\"F5Telemetry_LTM_CL\", \"F5Telemetry_system_CL\", \"F5Telemetry_ASM_CL\"],\n", " \"F5\": [\"CommonSecurityLog (F5)\"],\n", " \"Fortinet\": [\"CommonSecurityLog (Fortinet)\"],\n", " \"MicrosoftCloudAppSecurity\": [\"SecurityAlert (MCAS)\", \"McasShadowItReporting\"],\n", " \"MicrosoftDefenderAdvancedThreatProtection\": [\"SecurityAlert (MDATP)\"],\n", " \"WAF\": [\"AzureDiagnostics (Application Gateways)\"],\n", " \"Office365\": [\n", " \"OfficeActivity (SharePoint)\",\n", " \"OfficeActivity (Exchange)\",\n", " \"OfficeActivity (Teams)\",\n", " ],\n", " \"OfficeATP\": [\"SecurityAlert (Office 365 Security & Compliance)\"],\n", " \"OneIdentity\": [\"CommonSecurityLog (OneIdentity)\"],\n", " \"PaloAltoNetworks\": [\"CommonSecurityLog (PaloAlto)\"],\n", " \"SecurityEvents\": [\"SecurityEvents\"],\n", " \"Symantec\": [\"SymantecICDx_CL\"],\n", " \"Syslog\": [\"Syslog\"],\n", " \"ThreatIntelligenceTaxii\": [\"ThreatIntelligenceIndicator\"],\n", " \"ThreatIntelligence\": [\"ThreatIntelligenceIndicator\"],\n", " \"TrendMicro\": [\"CommonSecurityLog (TrendMicroDeepSecurity)\"],\n", " \"WindowsEventForwarding\": [\"WindowsEvent\"],\n", " \"WindowsFireWall\": [\"WindowsFirewall\"],\n", " \"Zscaler\": [\"CommonSecurityLog (Zscaler)\"],\n", " \"BehaviorAnalytics\": [\"BehaviorAnalytics\"],\n", "}\n", "\n", "# Set Mitre ATT&CK categories\n", "mitre = [\n", " \"Reconnaissance\",\n", " \"ResourceDevelopment\",\n", " \"InitialAccess\",\n", " \"Execution\",\n", " \"Persistence\",\n", " \"PrivilegeEscalation\",\n", " \"DefenseEvasion\",\n", " \"CredentialAccess\",\n", " \"Discovery\",\n", " \"LateralMovement\",\n", " \"Collection\",\n", " \"CommandAndControl\",\n", " \"Exfiltration\",\n", " \"Impact\",\n", "]\n", "\n", "# Set entity identifiers\n", "entity_identifiers = {\n", " \"Account\": [\n", " \"Name\",\n", " \"FullName\",\n", " \"NTDomain\",\n", " \"DnsDomain\",\n", " \"UPNSuffix\",\n", " \"Sid\",\n", " \"AadTenantId\",\n", " \"AadUserId\",\n", " \"PUID\",\n", " \"IsDomainJoined\",\n", " \"DisplayName\",\n", " \"ObjectGuid\",\n", " ],\n", " \"Host\": [\n", " \"DnsDomain\",\n", " \"NTDomain\",\n", " \"HostName\",\n", " \"FullName\",\n", " \"NetBiosName\",\n", " \"AzureID\",\n", " \"OMSAgentID\",\n", " \"OSFamily\",\n", " \"OSVersion\",\n", " \"IsDomainJoined\",\n", " ],\n", " \"IP\": [\"Address\"],\n", " \"Malware\": [\"Name\", \"Category\"],\n", " \"File\": [\"Directory\", \"Name\"],\n", " \"Process\": [\"ProcessId\", \"CommandLine\", \"ElevationToken\", \"CreationTimeUtc\"],\n", " \"CloudApplication\": [\"AppId\", \"Name\", \"InstanceName\"],\n", " \"DNS\": [\"DomainName\"],\n", " \"AzureResource\": [\"ResourceId\"],\n", " \"FileHash\": [\"Algorithm\", \"Value\"],\n", " \"RegistryKey\": [\"Hive\", \"Key\"],\n", " \"RegistryValue\": [\"Name\", \"Value\", \"ValueType\"],\n", " \"SecurityGroup\": [\"DistinguishedName\", \"SID\", \"ObjectGuid\"],\n", " \"URL\": [\"Url\"],\n", " \"Mailbox\": [\n", " \"MailboxPrimaryAddress\",\n", " \"DisplayName\",\n", " \"Upn\",\n", " \"ExternalDirectoryObjectId\",\n", " \"RiskLevel\",\n", " ],\n", " \"MailCluster\": [\n", " \"NetworkMessageIds\",\n", " \"CountByDeliveryStatus\",\n", " \"CountByThreatType\",\n", " \"CountByProtectionStatus\",\n", " \"Threats\",\n", " \"Query\",\n", " \"QueryTime\",\n", " \"MailCount\",\n", " \"IsVolumeAnomaly\",\n", " \"Source\",\n", " \"ClusterSourceIdentifier\",\n", " \"ClusterSourceType\",\n", " \"ClusterQueryStartTime\",\n", " \"ClusterQueryEndTime\",\n", " \"ClusterGroup\",\n", " ],\n", " \"MailMessage\": [\n", " \"Recipient\",\n", " \"Urls\",\n", " \"Threats\",\n", " \"Sender\",\n", " \"P1Sender\",\n", " \"P1SenderDisplayName\",\n", " \"P1SenderDomain\",\n", " \"SenderIP\",\n", " \"P2Sender\",\n", " \"P2SenderDisplayName\",\n", " \"P2SenderDomain\",\n", " \"ReceivedDate\",\n", " \"NetworkMessageId\",\n", " \"InternetMessageId\",\n", " \"Subject\",\n", " \"BodyFingerprintBin1\",\n", " \"BodyFingerprintBin2\",\n", " \"BodyFingerprintBin3\",\n", " \"BodyFingerprintBin4\",\n", " \"BodyFingerprintBin5\",\n", " \"AntispamDirection\",\n", " \"DeliveryAction\",\n", " \"DeliveryLocation\",\n", " \"Language\",\n", " \"ThreatDetectionMethods\",\n", " ],\n", " \"SubmissionMail\": [\n", " \"NetworkMessageId\",\n", " \"Timestamp\",\n", " \"Recipient\",\n", " \"Sender\",\n", " \"SenderIp\",\n", " \"Subject\",\n", " \"ReportType\",\n", " \"SubmissionId\",\n", " \"SubmissionDate\",\n", " \"Submitter\",\n", " ],\n", "}" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [], "source": [ "name_layout = widgets.Layout(width=\"150px\")\n", "widget_layout = widgets.Layout(width=\"75%\")\n", "\n", "# Select datatype from connector ID\n", "def create_dts():\n", " datatype = []\n", " for connector in RequiredDataConnectors.value:\n", " datatype.extend(connectors[connector])\n", " return datatype\n", "\n", "\n", "# Create widgets to collect query elements\n", "QueryName = widgets.HBox(\n", " [\n", " widgets.Label(\"Query Name:\", layout=name_layout),\n", " widgets.Text(\n", " placeholder=\"The name of the query\", disabled=False, layout=widget_layout\n", " ),\n", " ],\n", " layout=widget_layout,\n", ")\n", "\n", "QueryDescription = widgets.HBox(\n", " [\n", " widgets.Label(\"Query Description:\", layout=name_layout),\n", " widgets.Textarea(\n", " placeholder=\"A description of the query - as a single line\",\n", " disabled=False,\n", " layout=widget_layout,\n", " rows=10,\n", " ),\n", " ],\n", " layout=widget_layout,\n", ")\n", "\n", "Severity = widgets.HBox(\n", " [\n", " widgets.Label(\"Severity:\", layout=name_layout),\n", " widgets.Dropdown(\n", " options=[\"Low\", \"Medium\", \"High\"],\n", " value=\"Medium\",\n", " disabled=False,\n", " layout=widget_layout,\n", " ),\n", " ],\n", " layout=widget_layout,\n", ")\n", "\n", "QueryPeriod = widgets.HBox(\n", " [\n", " widgets.Label(\"Query Period (hours):\", layout=name_layout),\n", " widgets.IntSlider(\n", " value=168,\n", " min=0,\n", " max=336,\n", " step=1,\n", " disabled=False,\n", " orientation=\"horizontal\",\n", " readout=True,\n", " layout=widget_layout,\n", " ),\n", " ],\n", " layout=widget_layout,\n", ")\n", "\n", "QueryFrequency = widgets.HBox(\n", " [\n", " widgets.Label(\"Query Frequency (hours):\", layout=name_layout),\n", " widgets.IntSlider(\n", " value=12,\n", " min=0,\n", " max=168,\n", " step=1,\n", " disabled=False,\n", " orientation=\"horizontal\",\n", " readout=True,\n", " layout=widget_layout,\n", " ),\n", " ],\n", " layout=widget_layout,\n", ")\n", "\n", "TriggerOperator = widgets.HBox(\n", " [\n", " widgets.Label(\"Trigger:\", layout=name_layout),\n", " widgets.Dropdown(\n", " options=[\"gt\", \"lt\", \"eq\"], value=\"gt\", disabled=False, layout=widget_layout\n", " ),\n", " ],\n", " layout=widget_layout,\n", ")\n", "\n", "TriggerThreshold = widgets.HBox(\n", " [\n", " widgets.Label(\"Trigger Threshold:\", layout=name_layout),\n", " widgets.IntSlider(\n", " value=1,\n", " min=0,\n", " max=10,\n", " step=1,\n", " disabled=False,\n", " orientation=\"horizontal\",\n", " readout=True,\n", " layout=widget_layout,\n", " ),\n", " ],\n", " layout=widget_layout,\n", ")\n", "\n", "Tactics = widgets.HBox(\n", " [\n", " widgets.Label(\"ATT&CK Tactics:\", layout=name_layout),\n", " widgets.SelectMultiple(\n", " options=mitre, value=[mitre[0]], disabled=False, layout=widget_layout\n", " ),\n", " ],\n", " layout=widget_layout,\n", ")\n", "\n", "Techniques = widgets.HBox(\n", " [\n", " widgets.Label(\"ATT&CK Techniques:\", layout=name_layout),\n", " widgets.Text(placeholder=\"T001, T001.1\", disabled=False, layout=widget_layout),\n", " ],\n", " layout=widget_layout,\n", ")\n", "\n", "Query = widgets.HBox(\n", " [\n", " widgets.Label(\"Query:\", layout=name_layout),\n", " widgets.Textarea(\n", " placeholder=\"Table | take 10\", disabled=False, layout=widget_layout, rows=20\n", " ),\n", " ],\n", " layout=widget_layout,\n", ")\n", "\n", "EntityCount = widgets.HBox(\n", " [\n", " widgets.Label(\"Number of Entities:\", layout=name_layout),\n", " widgets.IntSlider(\n", " value=1,\n", " min=0,\n", " max=5,\n", " step=1,\n", " disabled=False,\n", " continuous_update=False,\n", " orientation=\"horizontal\",\n", " layout=widget_layout,\n", " ),\n", " ],\n", " layout=widget_layout,\n", ")\n", "\n", "RequiredDataConnectors = widgets.SelectMultiple(\n", " options=list(connectors.keys()),\n", " value=[list(connectors.keys())[0]],\n", " disabled=False,\n", " descriptoin=\"Data Connectors\",\n", " layout=widget_layout,\n", ")\n", "\n", "DataTypes = widgets.SelectMultiple(\n", " options=create_dts(), description=\"DataType\", disabled=False, layout=widget_layout\n", ")\n", "\n", "Kind = widgets.Dropdown(\n", " options=[\"scheduled\", \"NRT\"], disabled=False, description=\"Alert Type\"\n", ")\n", "\n", "extra_ents = widgets.Textarea(\n", " placeholder='Add additional entities',\n", " description='Add Entities:',\n", " disabled=False,\n", " layout=widget_layout\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a name=\"analytics\"></a>\n", "# Create an Analytics Query\n", "\n", "Use the following cells to create an Azure Sentinel Analytics Query. Complete the widgets in the next cells with details of your analytics query and then run the cells below to create an analytics query in the required template format and then write it to disk.\n", "\n", "For hunting queries use the [Create a Hunting Query](#hunting) section of this notebook." ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Complete your query details:\n", "For details of what is required in each section see https://github.com/Azure/Azure-Sentinel/wiki/Query-Style-Guide\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "18cae59fecd2494f8aa2ff7b80f463a2", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(Label(value='Query Name:', layout=Layout(width='150px')), Text(value='', layout=Layout(width='7…" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "9db14f96e41845708ea9d9090c8170bd", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(Label(value='Query Description:', layout=Layout(width='150px')), Textarea(value='', layout=Layo…" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "3314134f811a47f8b87f6b1a54726e4d", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(Label(value='Severity:', layout=Layout(width='150px')), Dropdown(index=1, layout=Layout(width='…" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "ae4da1699f984b67ad4364f63b0182ea", "version_major": 2, "version_minor": 0 }, "text/plain": [ "interactive(children=(SelectMultiple(description='DataConnector', index=(0,), layout=Layout(width='75%'), opti…" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "b74f0b5e8282400f825a3dc62cdd5a2d", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(Label(value='Query Period (hours):', layout=Layout(width='150px')), IntSlider(value=168, layout…" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "12d3b032288a4246a806889b1c518f62", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(Label(value='Query Frequency (hours):', layout=Layout(width='150px')), IntSlider(value=12, layo…" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "24a1c3e9cc994cefa165418952d19537", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(Label(value='Trigger:', layout=Layout(width='150px')), Dropdown(layout=Layout(width='75%'), opt…" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "38c566767d944c129782baf49a5c8fc4", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(Label(value='Trigger Threshold:', layout=Layout(width='150px')), IntSlider(value=1, layout=Layo…" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "162deeddd8ce4afba8384ced3728b478", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(Label(value='ATT&CK Tactics:', layout=Layout(width='150px')), SelectMultiple(index=(0,), layout…" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "28867832692142acb8f24ce261a85231", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(Label(value='ATT&CK Techniques:', layout=Layout(width='150px')), Text(value='', layout=Layout(w…" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "d31ef7eb11f3471bacb98cc1875a72f0", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(Label(value='Query:', layout=Layout(width='150px')), Textarea(value='', layout=Layout(width='75…" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "c9ce74d4fbac4a6ca02b8e09a985ab03", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Dropdown(description='Alert Type', options=('scheduled', 'NRT'), value='scheduled')" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Display widgets used to enter analytic query details\n", "print(\"Complete your query details:\")\n", "print(\"For details of what is required in each section see https://github.com/Azure/Azure-Sentinel/wiki/Query-Style-Guide\")\n", "display(QueryName)\n", "display(QueryDescription)\n", "display(Severity)\n", "\n", "\n", "@interact(DataConnector=RequiredDataConnectors, dtype=DataTypes)\n", "def select_datatypes(DataConnector, dtype):\n", " DataTypes.options = create_dts()\n", "\n", "\n", "display(QueryPeriod)\n", "display(QueryFrequency)\n", "display(TriggerOperator)\n", "display(TriggerThreshold)\n", "display(Tactics)\n", "display(Techniques)\n", "display(Query)\n", "display(Kind)" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Select values to extract as Entities (max of 5): \n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "2a5c578057c44f5596eb36abaa5e4de5", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(Label(value='Number of Entities:', layout=Layout(width='150px')), SelectMultiple(layout=Layout(…" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "If there are additional fields you want to extract as entities add them as a comma seperated list below:\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "75528dd879724e999da7d2b3e173395b", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Textarea(value='', description='Add Entities:', layout=Layout(width='75%'), placeholder='Add additional entiti…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "print(\"Select values to extract as Entities (max of 5): \")\n", "\n", "# Parse out any extended columns that might be entities that a user would want to extract\n", "lines = Query.children[1].value.split(\"|\")\n", "items = []\n", "for line in lines:\n", " if \"extend\" in line:\n", " items.extend(re.split(\" |=|,\", line))\n", "items = [i for i in items if i not in [None, \"extend\", \"timestamp\", \"\"]]\n", "set(items)\n", "\n", "# Let the user select columns they want to extract as entities\n", "ents = widgets.HBox(\n", " [\n", " widgets.Label(\"Number of Entities:\", layout=name_layout),\n", " widgets.SelectMultiple(\n", " options=list(items), disabled=False, layout=widget_layout\n", " ),\n", " ],\n", " layout=widget_layout,\n", ")\n", "display(ents)\n", "print(\"If there are additional fields you want to extract as entities add them as a comma seperated list below:\")\n", "display(extra_ents)" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [], "source": [ "# Have user select the entity type of each value selected for extraction\n", "all_ents = ents.children[1].value + tuple(extra_ents.value.split(\",\")) if extra_ents.value else ents.children[1].value\n", "for ent in all_ents:\n", " print(f\"Select the entity type of {ent}:\")\n", " globals()[ent+\"widget\"] = widgets.Dropdown(options=entity_identifiers.keys())\n", " display(globals()[ent+\"widget\"])" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Select identifier type for RoleName of type Account:\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "800c448aee8046efaade2fb233ace5dd", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Dropdown(options=('Name', 'FullName', 'NTDomain', 'DnsDomain', 'UPNSuffix', 'Sid', 'AadTenantId', 'AadUserId',…" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Select identifier type for IPCustomEntity of type Account:\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "b6a525261f5d468fb25be42fbb01f133", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Dropdown(options=('Name', 'FullName', 'NTDomain', 'DnsDomain', 'UPNSuffix', 'Sid', 'AadTenantId', 'AadUserId',…" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Select identifier type for AccountCustomEntity of type Account:\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "9b01653fa09545d28a1a1e08e8186df0", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Dropdown(options=('Name', 'FullName', 'NTDomain', 'DnsDomain', 'UPNSuffix', 'Sid', 'AadTenantId', 'AadUserId',…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Based on selected entities allow user to select the identifier type\n", "ent_mapping = []\n", "for ent in ents.children[1].value:\n", " ent_mapping.append({\"columnName\" : ent, \"entityType\" :globals()[ent+\"widget\"].value})\n", "\n", "for item in ent_mapping:\n", " ent=item['columnName']\n", " print(f\"Select identifier type for {item['columnName']} of type {item['entityType']}:\")\n", " globals()[ent+\"identwidget\"] = widgets.Dropdown(options=entity_identifiers[item['entityType']])\n", " display(globals()[ent+\"identwidget\"])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Generate unique GUID for the template\n", "q_guid = str(uuid.uuid4())\n", "# Get and format required data connectors and associated data types\n", "connector_id = \"\"\n", "if len(RequiredDataConnectors.value) == 0:\n", " connector_id += \"[]\"\n", "elif len(RequiredDataConnectors.value) == 1:\n", " connector_id += f\"- connectorId: {RequiredDataConnectors.value[0]}\"\n", " connector_id += \"\"\"\n", " dataTypes:\"\"\"\n", " for dtype in DataTypes.value:\n", " connector_id += f\"\"\"\n", " - {dtype}\"\"\"\n", "else:\n", " i = 0\n", " for conn in RequiredDataConnectors.value:\n", " if i == 0:\n", " connector_id += f\"- connectorId: {conn}\"\n", " else:\n", " connector_id += f\"\"\"\n", " - connectorId: {conn}\"\"\"\n", " connector_id += \"\"\"\n", " dataTypes:\"\"\"\n", " i+=1\n", " for dtype in DataTypes.value:\n", " if dtype in connectors[conn]:\n", " connector_id += f\"\"\"\n", " - {dtype}\"\"\"\n", "\n", "# Based on query period determine whether days or hours are best used\n", "if int(QueryFrequency.children[1].value/24) > 0:\n", " qfreq_val = f\"{int(QueryFrequency.children[1].value/24)}d\"\n", "else:\n", " qfreq_val = f\"{QueryFrequency.children[1].value}h\"\n", "if int(QueryPeriod.children[1].value/24) > 0:\n", " qperiod_val = f\"{int(QueryPeriod.children[1].value/24)}d\"\n", "else:\n", " qperiod_val = f\"{QueryPeriod.children[1].value}h\"\n", "\n", "# Get and format Mitre ATT&CK tactics and techniques\n", "att_tactics = \"tactics:\"\n", "for tact in Tactics.children[1].value:\n", " att_tactics += f\"\"\"\n", " - {tact}\"\"\"\n", "technique_ids = \"relevantTechniques:\"\n", "for tech in Techniques.children[1].value.split(\",\"):\n", " technique_ids += f\"\"\"\n", " - {tech.strip()}\"\"\"\n", "\n", "#Get and format entity mapping\n", "for ent in ents.children[1].value:\n", " for entm in ent_mapping:\n", " if entm['columnName'] == ent:\n", " entm.update({\"identifier\" :globals()[ent+\"identwidget\"].value})\n", "\n", "ent_ids = \"entityMappings:\"\n", "for ent in ent_mapping:\n", " ent_ids += f\"\"\"\n", " - entityType: {ent['entityType']}\n", " fieldMappings:\n", " - identifier: {ent['identifier']}\n", " columnName: {ent['columnName']}\"\"\"\n", "\n", "analytic_body = f\"\"\"id: {q_guid}\n", "name: {QueryName.children[1].value}\n", "description: |\n", " '{QueryDescription.children[1].value}'\n", "severity: {Severity.children[1].value}\n", "requiredDataConnectors:\n", " {connector_id}\n", "queryFrequency: {qfreq_val}\n", "queryPeriod: {qperiod_val}\n", "triggerOperator: {TriggerOperator.children[1].value}\n", "triggerThreshold: {TriggerThreshold.children[1].value}\n", "{att_tactics}\n", "{technique_ids}\n", "query: |\n", " {Query.children[1].value}\n", "{ent_ids}\n", "version: 1.0.0\n", "kind: {Kind.value}\n", "\"\"\"\n", "print(\"Your analytics query:\\n\")\n", "print(analytic_body)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you want to validate this query by running it against a Sentinel workspace go to the [validations](#validation) section." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Write file to disk with the name of the query\n", "file_name = QueryName.children[1].value.replace(\" \",'')\n", "with open(f\"{file_name}.yaml\", \"x\") as qfile:\n", " qfile.write(analytic_body)\n", " print(f\"Query written to {file_name}.yaml\")" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "<a name=\"hunting\"></a>\n", "# Create a Hunting Query\n", "\n", "Use the following cells to create an Azure Sentinel Hunting Query. Complete the widgets in the next cells with details of your analytics query and then run the cells below to create an analytics query in the required template format and then write it to disk.\n", "\n", "For analytics queries use the [Create an Analytics Query](#analytics) section of this notebook." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Display widgets for the elements required in the Hunting Query template\n", "print(\"Complete your query details:\")\n", "display(QueryName)\n", "display(QueryDescription)\n", "@interact(dconnector = RequiredDataConnectors, dtype = DataTypes)\n", "def select_datatypes(dconnector, dtype):\n", " DataTypes.options = create_dts()\n", "display(Tactics)\n", "display(Techniques)\n", "display(Query)" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Select values to extract as Entities (max of 5): \n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "a6744a7a23b2441aaf1fa408494246af", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(Label(value='Number of Entities:', layout=Layout(width='150px')), SelectMultiple(layout=Layout(…" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "If there are additional fields you want to extract as entities add them as a comma seperated list below:\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "1e502f7ea1094481ab06169d2629d0cf", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Textarea(value='', description='Add Entities:', placeholder='Add additional entities')" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "print(\"Select values to extract as Entities (max of 5): \")\n", "\n", "# Parse out any extended columns that might be entities that a user would want to extract\n", "lines = Query.children[1].value.split(\"|\")\n", "items = []\n", "for line in lines:\n", " if \"extend\" in line:\n", " items.extend(re.split(\" |=|,\", line))\n", "items = [i for i in items if i not in [None, \"extend\", \"timestamp\", \"\"]]\n", "set(items)\n", "\n", "# Let the user select columns they want to extract as entities\n", "ents = widgets.HBox([widgets.Label('Number of Entities:', layout=name_layout),\n", " widgets.SelectMultiple(\n", " options=list(items),\n", " disabled=False,\n", " layout=widget_layout\n", " )],\n", " layout=widget_layout)\n", "display(ents)\n", "print(\"If there are additional fields you want to extract as entities add them as a comma seperated list below:\")\n", "display(extra_ents)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Have user select the entity type of each value selected for extraction\n", "for ent in ents.children[1].value:\n", " print(f\"Select the entity type of {ent}:\")\n", " globals()[ent+\"widget\"] = widgets.Dropdown(options=entity_identifiers.keys())\n", " display(globals()[ent+\"widget\"])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Based on selected entities allow user to select the identifier type\n", "ent_mapping = []\n", "for ent in ents.children[1].value:\n", " ent_mapping.append({\"columnName\" : ent, \"entityType\" :globals()[ent+\"widget\"].value})\n", "\n", "for item in ent_mapping:\n", " ent=item['columnName']\n", " print(f\"Select identifier type for {item['columnName']} of type {item['entityType']}:\")\n", " globals()[ent+\"identwidget\"] = widgets.Dropdown(options=entity_identifiers[item['entityType']])\n", " display(globals()[ent+\"identwidget\"])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Generate unique GUID for the template\n", "q_guid = str(uuid.uuid4())\n", "# Get and format Data Connector and Data Type elemtns\n", "connector_id = \"\"\n", "if len(RequiredDataConnectors.value) == 0:\n", " connector_id += \"[]\"\n", "elif len(RequiredDataConnectors.value) == 1:\n", " connector_id += f\"- connectorId: {RequiredDataConnectors.value[0]}\"\n", " connector_id += \"\"\"\n", " dataTypes:\"\"\"\n", " for dtype in DataTypes.value:\n", " connector_id += f\"\"\"\n", " - {dtype}\"\"\"\n", "else:\n", " i = 0\n", " for conn in RequiredDataConnectors.value:\n", " if i == 0:\n", " connector_id += f\"- connectorId: {conn}\"\n", " else:\n", " connector_id += f\"\"\"\n", " - connectorId: {conn}\"\"\"\n", " connector_id += \"\"\"\n", " dataTypes:\"\"\"\n", " i+=1\n", " for dtype in DataTypes.value:\n", " if dtype in connectors[conn]:\n", " connector_id += f\"\"\"\n", " - {dtype}\"\"\"\n", "\n", "# Get and format Mitre ATT&CK tactics and techniques\n", "att_tactics = \"tactics:\"\n", "for tact in Tactics.children[1].value:\n", " att_tactics += f\"\"\"\n", " - {tact}\"\"\"\n", "technique_ids = \"relevantTechniques:\"\n", "for tech in Techniques.children[1].value.split(\",\"):\n", " technique_ids += f\"\"\"\n", " - {tech.strip()}\"\"\"\n", "\n", "# Build out entity mapps\n", "for ent in ents.children[1].value:\n", " for entm in ent_mapping:\n", " if entm['columnName'] == ent:\n", " entm.update({\"identifier\" :globals()[ent+\"identwidget\"].value})\n", "\n", "ent_ids = \"entityMappings:\"\n", "for ent in ent_mapping:\n", " ent_ids += f\"\"\"\n", " - entityType: {ent['entityType']}\n", " fieldMappings:\n", " - identifier: {ent['identifier']}\n", " columnName: {ent['columnName']}\"\"\"\n", "\n", "# Write out populated template body\n", "analytic_body = f\"\"\"id: {q_guid}\n", "name: {QueryName.children[1].value}\n", "description: |\n", " '{QueryDescription.children[1].value}'\n", "requiredDataConnectors:\n", " {connector_id}\n", "{att_tactics}\n", "{technique_ids}\n", "query: |\n", " {Query.children[1].value}\n", "{ent_ids}\n", "\"\"\"\n", "print(\"Your hunting query:\\n\")\n", "print(analytic_body)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you want to validate this query by running it against a Sentinel workspace go to the [validations](#validation) section." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Write the query file to disk with using the query title as the file name\n", "file_name = QueryName.children[1].value.replace(\" \",'')\n", "with open(f\"{file_name}.yaml\", \"x\") as qfile:\n", " qfile.write(analytic_body)\n", " print(f\"Query written to {file_name}.yaml\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a name=\"validation\"></a>\n", "## Query Validation\n", "\n", "If you want to validate your query by running it against a Sentinel Workspace run the code below. \n", "This is an optional step and requires use of [MSTICPy](https://readthedocs.org/projects/msticpy/).\n", "\n", "Enter your Microsoft Sentinel Workspace ID and Tenant ID below and the query created will be run against the specified workspace." ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "6df775fb64fc43a7af5a0509929da9b8", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Text(value='', description='Workspace ID:', placeholder='Enter your Workspace ID')" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "fd87a379783d42408377ef2104711248", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Text(value='', description='Tenant ID:', placeholder='Enter your Tennant ID')" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#query validotor\n", "ws_id = widgets.Text(\n", " placeholder='Enter your Workspace ID',\n", " description='Workspace ID:',\n", " disabled=False\n", ")\n", "\n", "ten_id = widgets.Text(\n", " placeholder='Enter your Tennant ID',\n", " description='Tenant ID:',\n", " disabled=False\n", ")\n", "\n", "display(ws_id)\n", "display(ten_id)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import msticpy as mp\n", "from msticpy.common.exceptions import MsticpyDataQueryError\n", "mp.init_notebook(\n", " namespace=globals()\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "qry_prov = mp.QueryProvider(\"AzureSentinel\")\n", "la_connection_string = f'loganalytics://code().tenant(\"{ten_id.value}\").workspace(\"{ws_id.value}\")'\n", "qry_prov.connect(connection_str=la_connection_string)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "qry_prov.exec_query(Query.children[1].value)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3.8 - AzureML", "language": "python", "name": "python38-azureml" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { "04a7427f23114b718c417fa9abf3f1ff": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "0564b9fab7ef49f58fdf8221fa1a90ef": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "0918038e90c746b7bb22f5358c8d00ce": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "75%" } }, "1cc4cb95749747fab73a8abb6cdbd1e1": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "2462306127924c7f8b492d5ed5c5e489": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "Query Frequency (hours):", "layout": "IPY_MODEL_7f2e46df02b947e98227918915fcc2ce", "max": 168, "style": "IPY_MODEL_5aa88a89fff3429197a6290e3baaefd9", "value": 1 } }, "28ca1cff49af4f1984742f30e8c79421": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextareaModel", "state": { "description": "String:", "layout": "IPY_MODEL_c96a323de09c4e9eb8bbf68e47534d56", "placeholder": "A description of the query", "rows": 10, "style": "IPY_MODEL_3523d282c3d7439192a9248309c86bd0", "value": "This query uses Windows Event ID 5136 in order to detect potential webshell deployment by exploitation of CVE-2021-27065. This query looks for changes to the InternalHostName or ExternalHostName properties of Exchange OAB Virtual Directory objects in AD Directory Services where the new objects contain potential webshell objects. Ref: https://aka.ms/ExchangeVulns" } }, "296621ed5e154f8b8aeb496d29d6fab7": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "_dom_classes": [ "widget-interact" ], "children": [ "IPY_MODEL_75c8374c27914d75a196d41505c6d037", "IPY_MODEL_c649a988e4be40f9815e69d05265dde4", "IPY_MODEL_ba968bf4310741fbaa4714c3c89c68a7" ], "layout": "IPY_MODEL_3a5f668a428a4455b1babe96bf791bf8" } }, "2c97f734ebe14588bd8c42bbc3c2232f": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "75%" } }, "2d62aedcd2a34bceb0d0ce3e9b3b0215": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "334852e3f33a490abd483cc56ed48956": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "75%" } }, "3497245005a242c0866a0709d3b76ea6": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "3523d282c3d7439192a9248309c86bd0": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "3a5f668a428a4455b1babe96bf791bf8": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "3c2aa87efd8a494a80808b828be32f72": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "3f383d51014e49649159ecaa40230340": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "75%" } }, "44f9260ada7f41babd2ade7d5a32774b": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DropdownModel", "state": { "_options_labels": [ "gt", "lt", "eq" ], "description": "Trigger:", "index": 0, "layout": "IPY_MODEL_dd3d3deced4c42e9af3c0865f22d2b73", "style": "IPY_MODEL_3c2aa87efd8a494a80808b828be32f72" } }, "486ff814a28c43b5973b78f21bdb1786": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "4b6763e33aef463e955a61473d4d537e": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "5aa88a89fff3429197a6290e3baaefd9": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "5c78b12becf74402b11c8eebf8a36d77": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "5d616c17ce584cbd87878625405ce437": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "5e1ca083875346b1ad9e02539b3c08bf": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "604f0b9f32d64c7ab1bf6136c7fa6aac": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "666fd04b648540e7a66963da45d962fa": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DropdownModel", "state": { "_options_labels": [ "Account", "Host", "IP", "Malware", "File", "Process", "CloudApplication", "DNS", "AzureResource", "FileHash", "RegistryKey", "RegistryValue", "SecurityGroup", "URL", "Mailbox", "MailCluster", "MailMessage", "SubmissionMail" ], "index": 1, "layout": "IPY_MODEL_3497245005a242c0866a0709d3b76ea6", "style": "IPY_MODEL_604f0b9f32d64c7ab1bf6136c7fa6aac" } }, "69969a22c00146219e337375518eccd2": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SelectMultipleModel", "state": { "_options_labels": [ "Reconnaissance", "ResourceDevelopment", "InitialAccess", "Execution", "Persistence", "PrivilegeEscalation", "DefenseEvasion", "CredentialAccess", "Discovery", "LateralMovement", "Collection", "CommandAndControl", "Exfiltration", "Impact" ], "description": "ATT&CK Tactics:", "index": [ 2 ], "layout": "IPY_MODEL_0918038e90c746b7bb22f5358c8d00ce", "rows": 5, "style": "IPY_MODEL_6a583b0e608b4e5389df88d0270a541f" } }, "6a583b0e608b4e5389df88d0270a541f": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "75c8374c27914d75a196d41505c6d037": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SelectMultipleModel", "state": { "_options_labels": [ "AWS", "AzureActiveDirectory", "AzureActiveDirectoryIdentityProtection", "AzureActivity", "AzureAdvancedThreatProtection", "AzureInformationProtection", "AzureMonitor(IIS)", "AzureMonitor(VMInsights)", "AzureMonitor(WireData)", "AzureSecurityCenter", "IoT", "BarracudaCloudFirewall", "Barracuda", "CheckPoint", "CiscoASA", "Citrix", "CEF", "CyberArk", "DNS", "ExtraHopNetworks", "F5BigIp", "F5", "Fortinet", "MicrosoftCloudAppSecurity", "MicrosoftDefenderAdvancedThreatProtection", "WAF", "Office365", "OfficeATP", "OneIdentity", "PaloAltoNetworks", "SecurityEvents", "Symantec", "Syslog", "ThreatIntelligenceTaxii", "ThreatIntelligence", "TrendMicro", "WindowsEventForwarding", "WindowsFireWall", "Zscaler" ], "description": "Data Connectors", "index": [ 30 ], "layout": "IPY_MODEL_3f383d51014e49649159ecaa40230340", "rows": 5, "style": "IPY_MODEL_5d616c17ce584cbd87878625405ce437" } }, "7cfacb66f52748f5a4eb803f1a0e70c5": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "7f2e46df02b947e98227918915fcc2ce": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "75%" } }, "81f7830e6763427499ddee2242a6a48d": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "75%" } }, "854f9bcbe6ba4c21a265434512c816b9": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextModel", "state": { "description": "String:", "layout": "IPY_MODEL_f2bfc1f2bb3345799a7f31e070cce144", "placeholder": "The name of the query", "style": "IPY_MODEL_4b6763e33aef463e955a61473d4d537e", "value": "Exchange OAB Virtual Directory Attribute Containing Potential Webshell" } }, "8e22d0195c66445d88d15827aa4a53bf": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "90005b0bd56b4cea8dab78f431d3b3f8": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DropdownModel", "state": { "_options_labels": [ "DnsDomain", "NTDomain", "HostName", "FullName", "NetBiosName", "AzureID", "OMSAgentID", "OSFamily", "OSVersion", "IsDomainJoined" ], "index": 3, "layout": "IPY_MODEL_d17f193a3111499b98a082527d5ff207", "style": "IPY_MODEL_abe626e325c04fb992ca1bf8f21643f3" } }, "9d34a4a6ecfe49a5a4b1e4e0aa85bae1": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DropdownModel", "state": { "_options_labels": [ "Name", "FullName", "NTDomain", "DnsDomain", "UPNSuffix", "Sid", "AadTenantId", "AadUserId", "PUID", "IsDomainJoined", "DisplayName", "ObjectGuid" ], "index": 1, "layout": "IPY_MODEL_2d62aedcd2a34bceb0d0ce3e9b3b0215", "style": "IPY_MODEL_486ff814a28c43b5973b78f21bdb1786" } }, "a08f8d47a195494abcb70ece0b6e930d": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextareaModel", "state": { "description": "Query:", "layout": "IPY_MODEL_334852e3f33a490abd483cc56ed48956", "placeholder": "Table | take 10", "rows": 20, "style": "IPY_MODEL_5e1ca083875346b1ad9e02539b3c08bf", "value": "SecurityEvent\n// Look for specific Directory Service Changes\n| where EventID == 5136\n| extend Data = parse_xml(EventData)\n| extend ObjectClass = tostring( Data.EventData.Data[10].[\"#text\"])\n// Where changes relate to Exchange OAB\n| where ObjectClass =~ \"msExchOABVirtualDirectory\"\n| extend AttributeLDAPDisplayName = tostring( Data.EventData.Data[11].[\"#text\"])\n// Look for InternalHostName or ExternalHostName properties being changed\n| where AttributeLDAPDisplayName in (\"msExchExternalHostName\", \"msExchInternalHostName\")\n| extend DN = tostring(Data.EventData.Data[8].[\"#text\"])\n| extend AttributeValue = tostring(Data.EventData.Data[13].[\"#text\"])\n// Look for suspected webshell activity\n| where AttributeValue has \"script\"\n| project-reorder TimeGenerated, Computer, Account, DN, AttributeLDAPDisplayName, AttributeValue\n| extend timestamp = StartTime, AccountCustomEntity = Account, HostCustomEntity = Computer" } }, "a6697c75d3ab4163a2c24c1394519c82": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "abe626e325c04fb992ca1bf8f21643f3": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "af414585afc24bc6b5f0394353260b76": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "75%" } }, "b67ff40ec8464dde91cb242421ff2647": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "Trigger Threshold:", "layout": "IPY_MODEL_f51b4246ed1b4fa7b370cff443e306a4", "max": 10, "style": "IPY_MODEL_fe6724c0fecd4dd7a2e20f10bd939fcd" } }, "b7fc41432f3045cca3be355f453911af": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "75%" } }, "ba968bf4310741fbaa4714c3c89c68a7": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "layout": "IPY_MODEL_04a7427f23114b718c417fa9abf3f1ff" } }, "bc13534bb8354e3faebdfbccf4c906b2": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "continuous_update": false, "description": "Number of Entities:", "layout": "IPY_MODEL_81f7830e6763427499ddee2242a6a48d", "max": 5, "style": "IPY_MODEL_e4f0358e51dd4342b80821b17144e0c6", "value": 1 } }, "c649a988e4be40f9815e69d05265dde4": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SelectMultipleModel", "state": { "_options_labels": [ "SecurityEvents" ], "description": "DataType", "index": [ 0 ], "layout": "IPY_MODEL_b7fc41432f3045cca3be355f453911af", "rows": 5, "style": "IPY_MODEL_5c78b12becf74402b11c8eebf8a36d77" } }, "c96a323de09c4e9eb8bbf68e47534d56": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "75%" } }, "cf2b046de2f34aabb883f99cb04ec86b": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DropdownModel", "state": { "_options_labels": [ "Low", "Medium", "High" ], "description": "Severity:", "index": 2, "layout": "IPY_MODEL_2c97f734ebe14588bd8c42bbc3c2232f", "style": "IPY_MODEL_7cfacb66f52748f5a4eb803f1a0e70c5" } }, "cf79c03005764aadae91d90d861b3d18": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "75%" } }, "d17f193a3111499b98a082527d5ff207": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "d5238f1ce17242528c2e3748cc9010f6": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SelectMultipleModel", "state": { "_options_labels": [ "extend", "Data", "parse_xml(EventData)\n", "extend", "ObjectClass", "tostring(", "Data.EventData.Data[10].[\"#text\"])\n//", "Where", "changes", "relate", "to", "Exchange", "OAB\n", "extend", "AttributeLDAPDisplayName", "tostring(", "Data.EventData.Data[11].[\"#text\"])\n//", "Look", "for", "InternalHostName", "or", "ExternalHostName", "properties", "being", "changed\n", "extend", "DN", "tostring(Data.EventData.Data[8].[\"#text\"])\n", "extend", "AttributeValue", "tostring(Data.EventData.Data[13].[\"#text\"])\n//", "Look", "for", "suspected", "webshell", "activity\n", "extend", "timestamp", "StartTime", "AccountCustomEntity", "Account", "HostCustomEntity", "Computer" ], "description": "Select Entities", "index": [ 39, 41 ], "layout": "IPY_MODEL_e7d6f520cc7a46d4af02bc0bf8938936", "rows": 5, "style": "IPY_MODEL_1cc4cb95749747fab73a8abb6cdbd1e1" } }, "dd3d3deced4c42e9af3c0865f22d2b73": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "75%" } }, "dfdc7fda0a27437ca57bacdea945b985": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "e4f0358e51dd4342b80821b17144e0c6": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } }, "e7d6f520cc7a46d4af02bc0bf8938936": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "ee472307b150430ca05f374164c682d2": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "description": "Query Period (hours):", "layout": "IPY_MODEL_cf79c03005764aadae91d90d861b3d18", "max": 336, "style": "IPY_MODEL_0564b9fab7ef49f58fdf8221fa1a90ef", "value": 1 } }, "f2bfc1f2bb3345799a7f31e070cce144": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "75%" } }, "f3effbb2b3194e75a3bed73e0dcd6b84": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DropdownModel", "state": { "_options_labels": [ "Account", "Host", "IP", "Malware", "File", "Process", "CloudApplication", "DNS", "AzureResource", "FileHash", "RegistryKey", "RegistryValue", "SecurityGroup", "URL", "Mailbox", "MailCluster", "MailMessage", "SubmissionMail" ], "index": 0, "layout": "IPY_MODEL_8e22d0195c66445d88d15827aa4a53bf", "style": "IPY_MODEL_a6697c75d3ab4163a2c24c1394519c82" } }, "f40a6a190a5a4d03bb91cbee609e17f7": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextModel", "state": { "description": "ATT&CK Techniques:", "layout": "IPY_MODEL_af414585afc24bc6b5f0394353260b76", "placeholder": "T001, T001.1", "style": "IPY_MODEL_dfdc7fda0a27437ca57bacdea945b985", "value": "T1190" } }, "f51b4246ed1b4fa7b370cff443e306a4": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "75%" } }, "fe6724c0fecd4dd7a2e20f10bd939fcd": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "" } } }, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 4 }